home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Caml Light 0.61 / Source / src / compiler / modules.ml < prev    next >
Encoding:
Text File  |  1993-09-24  |  5.7 KB  |  205 lines  |  [TEXT/MPS ]

  1. (* modules.ml : handling of modules and global symbol tables *)
  2.  
  3. #open "misc";;
  4. #open "const";;
  5. #open "globals";;
  6. #open "errors";;
  7.  
  8. (* Informations associated with module names *)
  9.  
  10. type module =
  11.   { mod_name: string;                        (* name of the module *)
  12.     mod_values: (string, value_desc global) hashtbl__t;
  13.                                              (* table of values *)
  14.     mod_constrs: (string, constr_desc global) hashtbl__t;
  15.                                              (* table of constructors *)
  16.     mod_labels: (string, label_desc global) hashtbl__t;
  17.                                              (* table of labels *)
  18.     mod_types: (string, type_desc global) hashtbl__t;
  19.                                              (* table of type constructors *)
  20.     mutable mod_type_stamp: int;             (* stamp for type constructors *)
  21.     mutable mod_exc_stamp: int;              (* stamp for exceptions *)
  22.     mutable mod_persistent: bool }
  23.                       (* true if this interface comes from a .zi file *)
  24. ;;
  25.  
  26. let name_of_module    md = md.mod_name
  27. and values_of_module  md = md.mod_values
  28. and constrs_of_module md = md.mod_constrs
  29. and labels_of_module  md = md.mod_labels
  30. and types_of_module   md = md.mod_types
  31. ;;
  32.  
  33. (* The table of module interfaces already loaded in memory *)
  34.  
  35. let module_table = (hashtbl__new 37 : (string, module) hashtbl__t);;
  36.  
  37. let new_module nm =
  38.   let md =
  39.     { mod_name = nm;
  40.       mod_values = hashtbl__new 17;
  41.       mod_constrs = hashtbl__new 13;
  42.       mod_labels = hashtbl__new 11;
  43.       mod_types = hashtbl__new 7;
  44.       mod_type_stamp = 0;
  45.       mod_exc_stamp = 0;
  46.       mod_persistent = false }
  47.   in
  48.     hashtbl__add module_table nm md; md
  49. ;;
  50.  
  51. (* To load an interface from a file *)
  52.  
  53. let use_extended_zi = ref false;;
  54.  
  55. let read_module filename =
  56.   let ic = open_in_bin filename in
  57.   try
  58.     let md = (input_value ic : module) in
  59.     close_in ic;
  60.     md.mod_persistent <- true;
  61.     md
  62.   with End_of_file | Failure _ ->
  63.     close_in ic;
  64.     prerr_begline " Corrupted compiled interface file ";
  65.     prerr_endline filename;
  66.     raise Toplevel
  67. ;;
  68.  
  69. let load_module name =
  70.   let fullname = find_in_path (name ^ ".zi") in
  71.   let filename =
  72.     if !use_extended_zi & file_exists (fullname ^ "x")
  73.     then fullname ^ "x" else fullname in
  74.   read_module filename
  75. ;;
  76.  
  77. (* To find an interface by its name *)
  78.  
  79. let find_module filename =
  80.   let modname = filename__basename filename in
  81.   try
  82.     hashtbl__find module_table modname
  83.   with Not_found ->
  84.     let md = load_module filename in
  85.       hashtbl__add module_table modname md; md
  86. ;;
  87.  
  88. (* To remove the in-memory image of an interface *)
  89.  
  90. let kill_module name =
  91.   hashtbl__remove module_table name
  92. ;;
  93.  
  94. (* The current state of the compiler *)
  95.  
  96. let default_used_modules = ref ([] : string list);;
  97.  
  98. let defined_module = ref (new_module "")
  99. and used_modules = ref ([] : module list);;
  100.  
  101. let start_compiling_interface name =
  102.   defined_module := new_module name;
  103.   used_modules := map find_module !default_used_modules;;
  104.  
  105. let start_compiling_implementation name intf =
  106.   start_compiling_interface name;
  107.   !defined_module.mod_type_stamp <- intf.mod_type_stamp;
  108.   !defined_module.mod_exc_stamp  <- intf.mod_exc_stamp;;
  109.  
  110. let compiled_module_name () =
  111.   !defined_module.mod_name
  112. ;;
  113.  
  114. let defined_global name desc =
  115.   { qualid = { qual=compiled_module_name(); id=name }; info = desc }
  116. ;;
  117.  
  118. let new_type_stamp () =
  119.   let s = succ !defined_module.mod_type_stamp in
  120.   !defined_module.mod_type_stamp <- s; s
  121. ;;
  122.  
  123. let new_exc_stamp () =
  124.   let s = succ !defined_module.mod_exc_stamp in
  125.   !defined_module.mod_exc_stamp <- s; s
  126. ;;
  127.  
  128. (* Additions to the module being compiled *)
  129.  
  130. let add_global_info sel_fct glob =
  131.   let tbl = sel_fct !defined_module in
  132.     if !toplevel then
  133.       add_rollback (fun () -> hashtbl__remove tbl glob.qualid.id);
  134.     hashtbl__add tbl glob.qualid.id glob
  135. ;;
  136.  
  137. let add_value = add_global_info values_of_module
  138. and add_constr = add_global_info constrs_of_module
  139. and add_label = add_global_info labels_of_module
  140. and add_type = add_global_info types_of_module
  141. ;;
  142.  
  143. (* Find the descriptor for a reference to a global identifier.
  144.    If the identifier is qualified (mod__name), just look into module mod.
  145.    If the identifier is not qualified, look into the current module,
  146.    then into all opened modules. *)
  147.  
  148. exception Desc_not_found;;
  149.  
  150. let find_desc sel_fct = function
  151.     GRmodname q ->
  152.       begin try
  153.         hashtbl__find (sel_fct (find_module q.qual)) q.id
  154.       with Not_found ->
  155.         raise Desc_not_found
  156.       end
  157.   | GRname s ->
  158.       begin try
  159.         hashtbl__find (sel_fct !defined_module) s
  160.       with Not_found ->
  161.         let rec find_rec = function
  162.           []       -> raise Desc_not_found
  163.         | md::rest -> try hashtbl__find (sel_fct md) s
  164.                       with Not_found -> find_rec rest
  165.         in find_rec !used_modules
  166.       end
  167. ;;
  168.  
  169. let find_value_desc = find_desc values_of_module
  170. and find_constr_desc = find_desc constrs_of_module
  171. and find_label_desc = find_desc labels_of_module
  172. and find_type_desc = find_desc types_of_module
  173. ;;
  174.  
  175. let type_descr_of_type_constr cstr =
  176.   let rec select_type_descr = function
  177.     [] -> raise Desc_not_found
  178.   | desc::rest ->
  179.       if desc.info.ty_constr.info.ty_stamp = cstr.info.ty_stamp
  180.       then desc
  181.       else select_type_descr rest in
  182.   select_type_descr
  183.     (hashtbl__find_all
  184.       (types_of_module (find_module cstr.qualid.qual))
  185.       cstr.qualid.id)
  186. ;;
  187.  
  188. (* To write the interface of the module currently compiled *)
  189.  
  190. let write_compiled_interface oc =
  191.   output_value oc !defined_module
  192. ;;
  193.  
  194. (* To flush all in-core modules coming from .zi files *)
  195.  
  196. let flush_module_cache () =
  197.   let used = map (fun md -> md.mod_name) !used_modules in
  198.   hashtbl__do_table
  199.     (fun name md -> if md.mod_persistent then kill_module name)
  200.     module_table;
  201.   used_modules := map find_module used
  202. ;;
  203.  
  204.  
  205.